{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#  Convolutional Neural Network\n",
    "\n",
    "### Convolutional Layers: [128,128] ; Dense Layers [128,128]\n",
    "\n",
    "CNN is trained on raw data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Get the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Stored variables and their in-db values:\n",
      "X_test              -> defaultdict(<class 'list'>, {0: array([[[  9.38349\n",
      "X_train             -> array([[[ 0.00880131,  0.00116885,  0.00790277, ..\n",
      "snrs                -> [-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, \n",
      "y_test              -> defaultdict(<class 'list'>, {0: array([2, 6, 6, ..\n",
      "y_train             -> array([3, 6, 0, ..., 0, 4, 6])\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from collections import defaultdict\n",
    "from time import time\n",
    "\n",
    "%store -r\n",
    "%store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training data:  (80000, 2, 128) and labels:  (80000,)\n",
      "\n",
      "Test data:\n",
      "Total 20 (4000, 2, 128) arrays for SNR values:\n",
      "[-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n"
     ]
    }
   ],
   "source": [
    "print(\"Training data: \", X_train.shape, \"and labels: \", y_train.shape)\n",
    "print()\n",
    "print(\"Test data:\")\n",
    "print(\"Total\", len(X_test), X_test[18].shape, \"arrays for SNR values:\")\n",
    "print(sorted(X_test.keys()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Standardize the features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training set (80000, 2, 128)\n",
      "Test set corresponding to one snr value (4000, 2, 128)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "sc = StandardScaler()\n",
    "_X_train = np.reshape(X_train, [X_train.shape[0], X_train.shape[1]*X_train.shape[2]])\n",
    "_X_train = sc.fit_transform(_X_train)\n",
    "\n",
    "X_train = np.reshape(_X_train, X_train.shape)\n",
    "print(\"Training set\", X_train.shape)\n",
    "\n",
    "_X_test = defaultdict(list)\n",
    "for snr in snrs:\n",
    "    _X_test[snr] = np.reshape(X_test[snr], [X_test[snr].shape[0], X_test[snr].shape[1]*X_test[snr].shape[2]])\n",
    "    _X_test[snr] = sc.transform(_X_test[snr])\n",
    "    X_test[snr] = np.reshape(_X_test[snr], X_test[snr].shape)\n",
    "    \n",
    "print(\"Test set corresponding to one snr value\", X_test[18].shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Design and train the CNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0 training accuracy : 0.3212890625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep4\n",
      "Epoch 1 training accuracy : 0.37109375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep4\n",
      "Epoch 2 training accuracy : 0.4150390625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep4\n",
      "Epoch 3 training accuracy : 0.451171875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep4\n",
      "Epoch 4 training accuracy : 0.53515625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep4\n",
      "Epoch 5 training accuracy : 0.6005859375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep4\n",
      "Epoch 6 training accuracy : 0.6201171875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep4\n",
      "Epoch 7 training accuracy : 0.615234375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep4\n",
      "Epoch 8 training accuracy : 0.6572265625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep4\n",
      "Epoch 9 training accuracy : 0.673828125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep4\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep4\n",
      "Training took 28.530197 minutes\n"
     ]
    }
   ],
   "source": [
    "height = 2\n",
    "width = 128\n",
    "channels = 1\n",
    "n_features = height * width\n",
    "\n",
    "feature_map1 = 128\n",
    "ksize_conv1 = 2\n",
    "stride_conv1 = 1\n",
    "\n",
    "feature_map2 = 128\n",
    "ksize_conv2 = 2\n",
    "stride_conv2 = 1\n",
    "\n",
    "pool_layer_maps = 128\n",
    "\n",
    "n_fully_conn1 = 128\n",
    "n_fully_conn2 = 128\n",
    "\n",
    "n_classes = 8\n",
    "  \n",
    "X = tf.placeholder(tf.float32, shape=[None, height, width])\n",
    "X_reshaped = tf.reshape(X, shape=[-1, height, width, channels])\n",
    "labels = tf.placeholder(tf.int32, shape=[None])\n",
    "\n",
    "xavier_init = tf.contrib.layers.xavier_initializer()\n",
    "relu_act = tf.nn.relu\n",
    "\n",
    "# ------------------ Convolutional layers ----------------------------\n",
    "\n",
    "def convolutional_layer(X, filter_, ksize, kernel_init, strides, padding):\n",
    "    convolutional_layer = tf.layers.conv2d(X, filters = filter_, kernel_initializer = kernel_init,\n",
    "                                           kernel_size = ksize, strides = strides,\n",
    "                                          padding = padding, activation = relu_act)\n",
    "    return convolutional_layer\n",
    "\n",
    "conv_layer1 = convolutional_layer(X_reshaped, feature_map1, ksize_conv1, xavier_init, stride_conv1, padding = \"SAME\")\n",
    "\n",
    "conv_layer2 = convolutional_layer(conv_layer1, feature_map2, ksize_conv2, xavier_init, stride_conv2, padding = \"SAME\")\n",
    "\n",
    "# ----------------- Pooling layers -------------------------------------\n",
    "\n",
    "def pooling_layer(convlayer, ksize, strides, padding, pool_maps):\n",
    "    pool = tf.nn.max_pool(convlayer, ksize, strides, padding)\n",
    "    dim1, dim2 = int(pool.get_shape()[1]), int(pool.get_shape()[2])\n",
    "    pool_flat = tf.reshape(pool, shape = [-1, pool_maps * dim1 * dim2])\n",
    "    return pool_flat\n",
    "\n",
    "pool_layer_flat = pooling_layer(conv_layer2, [1,2,2,1], [1,2,2,1], \"VALID\", pool_layer_maps)\n",
    "\n",
    "# ----------------- Fully connected layers -------------------\n",
    "\n",
    "def dense_layer(input_layer, n_neurons, kernel_init, activation):\n",
    "    fully_conn = tf.layers.dense(inputs = input_layer, units = n_neurons, activation = activation,\n",
    "                                kernel_initializer = kernel_init)\n",
    "    return fully_conn\n",
    "        \n",
    "dense_layer1 = dense_layer(pool_layer_flat, n_fully_conn1, xavier_init, relu_act)\n",
    "\n",
    "dense_layer2 = dense_layer(dense_layer1, n_fully_conn2, xavier_init, relu_act)\n",
    "\n",
    "# ----------------- Output softmax layer ---------------------------\n",
    "\n",
    "logits = tf.layers.dense(dense_layer2, n_classes)\n",
    "softmax_activations = tf.nn.softmax(logits)\n",
    "\n",
    "# ----------------- Specify performance measure -------------------------------\n",
    "\n",
    "cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = logits, labels = labels)\n",
    "loss = tf.reduce_mean(cross_entropy)\n",
    "optimizer = tf.train.AdamOptimizer()\n",
    "train_operation = optimizer.minimize(loss)\n",
    "\n",
    "correct_predictions = tf.nn.in_top_k(logits, labels, 1)\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))\n",
    "\n",
    "# ---------------- Execution phase -------------------------------------------\n",
    "    \n",
    "n_epochs = 10\n",
    "batch_size = 1024\n",
    "n_train = X_train.shape[0]\n",
    "n_iter = n_train//batch_size\n",
    "\n",
    "acc_test = defaultdict(list)\n",
    "\n",
    "path = \"./CNN_narrow_deep4\"  \n",
    "saver = tf.train.Saver()\n",
    "\n",
    "start = time()\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    tf.global_variables_initializer().run()\n",
    "    for epoch in range(n_epochs):\n",
    "        for iteration in range(n_iter):\n",
    "            rand_indices = np.random.choice(n_train,batch_size)    \n",
    "            X_batch, y_batch = X_train[rand_indices], y_train[rand_indices]\n",
    "            sess.run(train_operation, feed_dict={X: X_batch, labels: y_batch})\n",
    "        acc_train = accuracy.eval(feed_dict={X: X_batch, labels: y_batch})\n",
    "        print(\"Epoch {} training accuracy : {}\".format(epoch, acc_train))\n",
    "        save_path = saver.save(sess, path)\n",
    "        saver.restore(sess, path)\n",
    "    saver.restore(sess, path)\n",
    "    for snr in snrs:\n",
    "        acc_test[snr] = accuracy.eval(feed_dict={X: X_test[snr], labels: y_test[snr]})\n",
    "\n",
    "print(\"Training took %f minutes\"%(float(time() - start)/60.0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Test the classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CNN's test accuracy on -20dB SNR samples = 0.12449999898672104\n",
      "CNN's test accuracy on -18dB SNR samples = 0.12425000220537186\n",
      "CNN's test accuracy on -16dB SNR samples = 0.1264999955892563\n",
      "CNN's test accuracy on -14dB SNR samples = 0.1392499953508377\n",
      "CNN's test accuracy on -12dB SNR samples = 0.1602499932050705\n",
      "CNN's test accuracy on -10dB SNR samples = 0.1837500035762787\n",
      "CNN's test accuracy on -8dB SNR samples = 0.2342499941587448\n",
      "CNN's test accuracy on -6dB SNR samples = 0.34950000047683716\n",
      "CNN's test accuracy on -4dB SNR samples = 0.5092499852180481\n",
      "CNN's test accuracy on -2dB SNR samples = 0.6602500081062317\n",
      "CNN's test accuracy on 0dB SNR samples = 0.7549999952316284\n",
      "CNN's test accuracy on 2dB SNR samples = 0.7919999957084656\n",
      "CNN's test accuracy on 4dB SNR samples = 0.8040000200271606\n",
      "CNN's test accuracy on 6dB SNR samples = 0.8087499737739563\n",
      "CNN's test accuracy on 8dB SNR samples = 0.8037499785423279\n",
      "CNN's test accuracy on 10dB SNR samples = 0.8169999718666077\n",
      "CNN's test accuracy on 12dB SNR samples = 0.8119999766349792\n",
      "CNN's test accuracy on 14dB SNR samples = 0.8097500205039978\n",
      "CNN's test accuracy on 16dB SNR samples = 0.8140000104904175\n",
      "CNN's test accuracy on 18dB SNR samples = 0.812250018119812\n"
     ]
    }
   ],
   "source": [
    "for snr in snrs:\n",
    "    print(\"CNN's test accuracy on {}dB SNR samples = {}\".format(snr,acc_test[snr]))  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Visualize classifier's performance on test set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nYyIiIiJZpJ4xERERkTTLqZ4xMxtrZh+Y2VwzuyTO8zuZ2d/M7B0ze8nMhmR6jCIiIiKZktFizMyK\ngNuBMcBewDgz273dYdOB+9x9X+Aq4NpMjrEzQZ/LVl5+ZilPecornLwgX1sh5CWS6Ttjo4B57j7f\n3UPAI8DR7Y7ZE3gJwN1fjvO8iIiISGBktGfMzI4Dxrj7xOj2eGCUu0+KOeZB4D/ufpuZHQs8Bgxw\n99XtzqWeMREREckLiXrGSjI9ljj72ldUFwG3m9kE4O/AQqAl3skmTJhAdXU1AFVVVYwcOZLRo0cD\nm28/alvb2ta2trWtbW1nervtcV1dHV1y94x9AQcDz8VsXwpckuD4nsCnnTznmTRz5kzlKS/nspSn\nPOUVTl6Qr60Q8qJ1S9x6p6jrci2lZgG7mtlwMysDTgCeij3AzPqbWdsdtJ8C92R4jCIiIiIZk/F1\nxsxsLHALkTcP3O3u15rZVGCWuz8T7Sv7FdBKZJrybI80+7c/j2d67CIiIiJbI1HPmBZ9FREREUmz\nnFr0NV/FNuQpT3m5kqU85SmvcPKCfG2FkJeIijERERGRLNI0pYiIiEiaaZpSREREJEepGEtS0Oey\nlZefWcpTnvIKJy/I11YIeYmoGBMRERHJIvWMiYiIiKSZesZEREREcpSKsSQFfS5befmZpTzlKa9w\n8oJ8bYWQl4iKMREREZEsUs+YiIiISJqpZ0xEREQkR6kYS1LQ57KVl59ZylOe8gonL8jXVgh5iagY\nExEREcki9YyJiIiIpJl6xkRERERylIqxJAV9Llt5+ZmlPOUpr3DygnxthZCXiIoxERERkSxSz5iI\niIhImqlnTERERCRHqRhLUtDnspWXn1nKU57yspNXW1vHGWdfxiFHjOOMsy+jtrYu7ZlBfS0LJS8R\nFWMiIiLdUFtbx7iJ05jbPJ6Gnt9lbvN4xk2clpGCLIjaCtvLrv7fjBW2uUY9YyIiIl1wd1atbaWi\nzDh/8uXMbR5PcWnlpufDoUaKl93D/5t0Gb16FNGzRxG9ehRRPaSUftsVb1N2bW0d10yfwYr6EAOq\nSpky+XRqaqq36Zy5oq2wLa+eRHFpJeFQI011t/LwnRen7Rqz9Xom6hlTMSYiIimX7wXE7Nom3pnX\nxKdLQpGvpSEaNjiXntKfX996FWv6nN3hZ2pfv5GaURduse+Sk/sx5uBeHY69+8l63vxw46airWcP\n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\nvBJ93Pb1DvAL4FfpHGCuCPpctvLyM2tr8/7y7/U0bHD2G1HO/iMq0p63LZSnPOVlPkt5mZXwzhiw\nB5G7YrOBrwArYp5rBha7+8Y0jU1E0uS4r/Wmb+9idhrc1R8BIiKSbsn2jJW7e059ILh6xkRERCRf\npGKdsSPN7GsxJ7zYzD4ysyejTfwiIiIishWSLcauBsoAzGxfIr1iDwD9gBvSM7TcEvS5bOXlZ5by\nlKe8wskL8rUVQl4iyTaMVAMfRB8fCzzp7leZ2TOA1hkTERER2UrJ9oytAg5x99lm9k/gAXe/08yq\ngdnunvSKkWY2FriZyF25u939uk6OOx54FPiCu78Z53n1jIl0w22PrmJw/xKO+kovysv04RsiIpm0\n1euMxfgXcJ2Z/R0YBZwQ3f85YGE3BlIE3A4cTmR9sllm9qS7f9DuuF7AucBryZ5bRDr38YJmnnh5\nPaUlcOh+lQzqp2JMRCRXJPsn8rlABXA6cJ67L4juPwp4sRt5o4B57j7f3UPAI8DRcY77BXAdkDPv\n4Az6XLby8jMr2bx7nl4DwHe+0ptB/bZtOYtcvD7lKa8Q8oJ8bYWQl0hSfyq7ex3w9Tj7z+1m3lDg\ns5jtBUQKtE3MbCQwzN2fNbOLunl+EWlndm0Tr767gYoy48Qx22V7OCIi0k5SPWMAZlYKjAF2Ae51\n97VmtiOwxt3XJnmO44FvuPvE6PZ44EB3Py+6bcBLwCnu/qmZzQQmu/sbcc6lnjGRJPzklqW89WET\nJ43ZjtOOrsr2cERECtI294xFG/VfAAYBlcDTwFrgJ0AP4Mwkx7IA2ClmexhbfrZlb2Av4OVoYTYY\neNLMjorXxD9hwgSqq6sBqKqqYuTIkYwePRrYfPtR29ou5O1RBx9KSwtsXPEaO5QPAL6WU+PTtra1\nre2gbrc9rquro0vu3uUX8CRwH1AKrAN2ju7/KvBRMueIHl8MfAQMJ7Ju2dvAHgmOnwns18lznkkz\nZ85UnvJyLiuZvNbWVl+8IpSxvFRTnvKUl/ks5aVetG6JW+8k28n7ZeDL7h6K3LDaZD4wJMlz4O5h\nMzsHeJ7NS1vMMbOpwCx3f6b9jxD5bEwR2UpmxuD++gxKEZFclew6Y6uJFGOzzWwdsK+7f2JmhwB/\ndPdB6R5onDF5MmMXERERybZUfDblC0SWt2jjZtYTuAJ4bhvHJyIiIlKwki3GJgNjzOy/RNYbewD4\n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\ngg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f3ab4839c50>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.style.use('classic')\n",
    "%matplotlib inline\n",
    "\n",
    "acc_test = sorted(acc_test.items())\n",
    "new_acc = []\n",
    "for i in range(len(acc_test)):\n",
    "    new_acc.append(acc_test[i][1])\n",
    "acc_test_values = new_acc \n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "x = snrs\n",
    "y = list(acc_test_values)\n",
    "plt.plot(x, y, marker=\"o\", linewidth=2.0, linestyle='dashed', color='royalblue')\n",
    "plt.axis([-20, 20, 0, 1])\n",
    "plt.xticks(np.arange(min(x), max(x)+1, 2.0))\n",
    "plt.yticks(np.arange(0, 1, 0.10))\n",
    "\n",
    "ttl = plt.title('SNR vs Accuracy', fontsize=16)\n",
    "ttl.set_weight('bold')\n",
    "plt.xlabel('SNR (dB)', fontsize=14)\n",
    "plt.ylabel('Test accuracy', fontsize=14)\n",
    "plt.grid()\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep4\n",
      "Confusion Matrix\n",
      "       8PSK  BPSK  CPFSK  GFSK  PAM4  QAM16  QAM64  QPSK\n",
      "8PSK   0.72  0.00   0.00  0.00  0.00   0.08   0.05  0.15\n",
      "BPSK   0.00  0.95   0.00  0.00  0.03   0.01   0.00  0.01\n",
      "CPFSK  0.02  0.00   0.96  0.00  0.00   0.00   0.00  0.01\n",
      "GFSK   0.01  0.00   0.00  0.98  0.00   0.00   0.00  0.00\n",
      "PAM4   0.00  0.02   0.00  0.00  0.98   0.00   0.00  0.00\n",
      "QAM16  0.03  0.00   0.00  0.00  0.00   0.49   0.48  0.00\n",
      "QAM64  0.02  0.00   0.00  0.00  0.00   0.46   0.52  0.01\n",
      "QPSK   0.11  0.01   0.00  0.00  0.00   0.03   0.00  0.86\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n/wJdqHiCK079DgAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f3a96f8e160>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Confusion Matrix\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    saver.restore(sess, path)\n",
    "    Z = logits.eval(feed_dict = {X : X_test[18]})\n",
    "    predicted_18dB = np.argmax(Z, axis = 1)\n",
    "    \n",
    "from sklearn.metrics import confusion_matrix\n",
    "%matplotlib inline\n",
    "\n",
    "classes = ['8PSK', 'BPSK', 'CPFSK', 'GFSK', 'PAM4', 'QAM16', 'QAM64', 'QPSK']\n",
    "conf_matrix = confusion_matrix(predicted_18dB, y_test[18])  \n",
    "\n",
    "conf_matrix = conf_matrix.astype('float') / conf_matrix.sum(axis=1)[:, np.newaxis]\n",
    "conf_matrix = conf_matrix.round(decimals = 2)\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame(data = conf_matrix, columns = classes, index = classes) \n",
    "print(\"Confusion Matrix\")\n",
    "print(df)\n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "plt.imshow(conf_matrix, interpolation = 'nearest', cmap = plt.cm.Purples)\n",
    "ticks = np.arange(len(classes))\n",
    "plt.title(\"Confusion Matrix\")\n",
    "plt.xticks(ticks, classes, rotation=45)\n",
    "plt.yticks(ticks, classes)\n",
    "\n",
    "plt.ylabel('True class')\n",
    "plt.xlabel('Predicted class')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "widgets": {
   "state": {},
   "version": "1.1.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
